package com.wd.study.pattern.factory;

/**
 * 工厂模式<BR>
 *
 * @author w4425
 * @version [V2.0.0, 2021/3/22]
 * @since V2.0.0
 */
class xxx {
    /**
     * 定义：定义一个用于创建对象的接口，但是让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类。
     * 工厂方法的优点：
     * <p>
     * 1、可扩展性，添加一个产品不用修改原来的代码，可以添加一个产品的实现类和一个工厂的实现类即可。
     * <p>
     * 2、隔离性，客户端只知道工厂就行，不需要知道创建产品的细节，实现系统解耦。
     * <p>
     * 缺点：
     * <p>
     * 1、每次增加一个产品都会增加相应的工厂类，这个可以用反射方式实现，避免过多的工厂类。
     * <p>
     * 工厂方法有好多的扩展和转换，即可以缩小为简单工厂，也可以扩展为延迟功能的工厂方法等。
     */
    /**
     * 产品类的公共接口
     */
    public interface IProduct {
        void method();
    }

    /**
     * 具体产品A
     */
    public class ProductA implements IProduct {

        @Override
        public void method() {
            System.out.println("产品A");
        }
    }

    /**
     * 具体产品B
     */
    public class ProductB implements IProduct {

        @Override
        public void method() {
            System.out.println("产品B");
        }
    }

    /**
     * 抽象工厂类
     */
    public abstract class AbsProductFactory {
        /**
         * 创建产品
         *
         * @return 产品
         */
        abstract IProduct createProduct();
    }

    /**
     * 具体工厂类A
     */
    public  class ConcreteFactoryA extends AbsProductFactory {

        @Override
        IProduct createProduct() {
            return new ProductA();
        }
    }

    /**
     * 具体工厂类B
     */
    public class ConcreteFactoryB extends AbsProductFactory {

        @Override
        IProduct createProduct() {
            return new ProductB();
        }
    }

    public  void main(String[] args) {
        AbsProductFactory factory = new ConcreteFactoryA();
        factory.createProduct();

        AbsF f = new FA();
        f.createPro().A();

    }

    public interface Pro{
        void A();
    }
    public class ProA implements Pro{

        @Override
        public void A() {

        }
    }
    public class ProB implements Pro{

        @Override
        public void A() {

        }
    }
    public abstract class AbsF{
       abstract Pro createPro();
    }
    public class FA extends AbsF{

        @Override
        Pro createPro() {
            return new ProA();
        }
    }


}
